﻿using System;
using System.IO;
using System.Xml.Serialization;
using System.Windows;
using System.Windows.Forms;

namespace Domotica.Gazing
{
    [Serializable]
    public class Config
    {
        public Config()
        {
            ScreenBounds = GetScreenBounds();
            ScreenSize = GetScreenSize(ScreenBounds);
            ScreenMiddle = GetScreenMiddle(ScreenBounds);

            Smoothing = 1;
            HorizontalGain = 6f;
            VerticalGain = 6f;

            ImageSize = new Size(320, 240);

            MouseClickRadius = 20;
            MouseClickDwell = 3000;
            MouseClicks = true;

            CameraNumber = 0;

            Calibrated = false;
        }

        public bool MouseClicks { get; set; }

        public string CameraName { get; set; }
        public int CameraNumber { get; set; }

        [XmlIgnore]
        public Rect ScreenBounds { get; set; }

        [XmlIgnore]
        public Size ScreenSize { get; set; }

        [XmlIgnore]
        public Point ScreenMiddle { get; set; }

        public float HorizontalGain { get; set; }
        public float VerticalGain { get; set; }
        public float Smoothing { get; set; }
        public bool ReverseHorizon { get; set; }
        public Size ImageSize { get; set; }

        public float MouseClickRadius { get; set; }

        public int MouseClickDwell { get; set; }

        public bool Calibrated { get; set; }

        public Point ScreenOffset
        {
            get; set;
        }

        private static string GetFileName()
        {
            return Path.Combine(System.Windows.Forms.Application.UserAppDataPath, "WebCamConfig.xml");
        }

        public void Save()
        {
            string fileName = GetFileName();

            Directory.CreateDirectory(System.Windows.Forms.Application.UserAppDataPath);

            StreamWriter sr = null;
            try
            {
                sr = new StreamWriter(fileName);
                var xs = new XmlSerializer(typeof (Config));
                xs.Serialize(sr, this);
            }
            catch (Exception ex)
            {
                //MessageBox.Show(ex.Message);
            }
            finally
            {
                if (sr != null)
                {
                    sr.Close();
                }
            }
        }

        public static Config Load()
        {
            string fileName = GetFileName();

            if (!File.Exists(fileName))
            {
                return null;
            }

            StreamReader sr = null;
            try
            {
                sr = new StreamReader(fileName);
                var xs = new XmlSerializer(typeof (Config));
                Config config = xs.Deserialize(sr) as Config;
                config.Calibrated = false;
                return config;
            }
            catch
            {
            }
            finally
            {
                if (sr != null)
                {
                    sr.Close();
                }
            }
            return null;
        }

        private static Size GetScreenSize(Rect bounds)
        {
            return new Size(bounds.Right - bounds.Left, bounds.Bottom - bounds.Top);
        }

        private static Point GetScreenMiddle(Rect bounds)
        {
            return new Point((bounds.Right - bounds.Left)/2 + bounds.Left, (bounds.Bottom - bounds.Top)/2 + bounds.Top);
        }

        private static Rect GetScreenBounds()
        {
            int bottom = int.MaxValue;
            int top = int.MinValue;
            int left = int.MaxValue;
            int right = int.MinValue;
            foreach (Screen screen in Screen.AllScreens)
            {
                bottom = Math.Min(screen.Bounds.Bottom, bottom);
                top = Math.Max(screen.Bounds.Top, top);
                left = Math.Min(screen.Bounds.Left, left);
                right = Math.Max(screen.Bounds.Right, right);
            }
            return new Rect(left, top, (right - left), (bottom - top));
        }
    }
}